﻿using System;
using System.Net;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Runtime.Serialization;

namespace Airport
{
    [DataContract]
    public class Route : IRoute, IEquatable<Route>
    {

        private int _routeId;
        private List<RouteNode> _routeNodes;
        private List<Taxiway> _taxiways;
        private List<Runway> _runways;

        /// <summary>
        /// Empty <c>Route</c> constructor.
        /// </summary>
        public Route()
            : this(-1)
        {
        }

        /// <summary>
        /// Creates a new <c>Route</c> with the given ID.
        /// </summary>
        /// <param name="routeId">int representing the explicit route ID for this <c>Route</c>.</param>
        public Route(int routeId)
        {
            _routeId = routeId;
            _routeNodes = new List<RouteNode>();
            _taxiways = new List<Taxiway>();
            _runways = new List<Runway>();
        }

        public Route(Flight flight)
        {
            //this.routeNodes = getShortestPath(flight.start, flight.end);
        }

        [DataMember]
        public int RouteId
        {
            get
            {
                return _routeId;
            }

            set
            {
                if (_routeId != value)
                {
                    _routeId = value;
                }
            }
        }

        [DataMember]
        public List<RouteNode> RouteNodes
        {
            get
            {
                return _routeNodes;
            }

            set
            {
                if (_routeNodes != value)
                {
                    _routeNodes = value;
                }
            }
        }

        [DataMember]
        public List<Taxiway> Taxiways
        {
            get
            {
                return _taxiways;
            }

            set
            {
                if (_taxiways != value)
                {
                    _taxiways = value;
                }
            }
        }

        [DataMember]
        public List<Runway> Runways
        {
            get
            {
                return _runways;
            }

            set
            {
                if (_runways != value)
                {
                    _runways = value;
                }
            }
        }

        public void SetTimes()
        {
        }

        public bool Equals(Route other)
        {
            if (other == null)
            {
                return false;
            }

            // Check that both routes have the same number of RouteNodes
            if (_routeNodes.Count != other._routeNodes.Count)
            {
                return false;
            }

            // Check that both routes have the same number of Taxiways
            if (_taxiways.Count != other._taxiways.Count)
            {
                return false;
            }

            // Check that both routes have the same number of Runways
            if (_runways.Count != other._runways.Count)
            {
                return false;
            }

            // Check that all RouteNodes are in both Routes
            foreach (RouteNode routeNode in other._routeNodes)
            {
                if (!_routeNodes.Contains(routeNode))
                {
                    return false;
                }
            }

            // Check that all Taxiways are in both Routes
            foreach (Taxiway taxiway in other._taxiways)
            {
                if (!_taxiways.Contains(taxiway))
                {
                    return false;
                }
            }

            // Check that all Runways are in both Routes
            foreach (Runway runway in other._runways)
            {
                if (!_runways.Contains(runway))
                {
                    return false;
                }
            }

            return true;
        }
    }

    
}
